﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using PivotData;
using PivotIO.XML;
using System.Linq;

namespace PivotIO.Tests
{
    /// <summary>
    /// Test out everything having to do with image I/O.
    /// </summary>
    [TestClass]
    public class ImageInfoIOTest
    {
        [TestInitialize]
        public void TestReset()
        {
            PivotIO.Tests.Utils.TestInit();
        }

        [TestCleanup]
        public void TestFinalize()
        {
            Utils.TestFinalize();
        }

        [TestMethod]
        public void TestLoadAndSaveImageInfo()
        {
            var mi = new ImageInfo[] { new ImageInfo() { Name = "dude", Id = 1, Extension = "png" } };

            ImageInfoIO.SaveAllImages(1, mi);

            var cn = ImageInfoIO.LoadAllImages(1);
            Assert.AreEqual(1, cn.Length, "length of images");
            Assert.AreEqual("dude", cn[0].Name, "name of image");
        }

        [TestMethod]
        public void TestDeleteAllImages()
        {
            var mi = new ImageInfo[] { new ImageInfo() { Name = "dude", Id = 1, Extension = "png" } };

            ImageInfoIO.SaveAllImages(1, mi);
            ImageInfoIO.DeleteAllImages(1);
            ImageInfoIO.WaitTillIOFlushed();

            var cn = ImageInfoIO.LoadAllImages(1);
            Assert.AreEqual(0, cn.Length, "length of images");
        }

        [TestMethod]
        public void TestLoadAndSaveImageInfoWithStringFacetFromCache()
        {
            var mi = new ImageInfo[] { new ImageInfo() { Name = "dude", Id = 1, Extension = "png" } };
            mi[0].Facets = new FacetAbsBase[] { new FacetString() { Name = "fork", Value = "this" } };

            ImageInfoIO.SaveAllImages(1, mi);

            var cn = ImageInfoIO.LoadAllImages(1);
            Assert.AreEqual(1, cn.Length, "length of images");
            Assert.AreEqual(1, cn[0].Facets.Length, "# fo facets");
            Assert.AreEqual("fork", cn[0].Facets[0].Name, "facet name");
            Assert.AreEqual("this", (cn[0].Facets[0] as FacetString).Value, "facet value");
        }

        [TestMethod]
        public void TestLoadAndSaveImageInfoWithStringFacetFromFile()
        {
            var mi = new ImageInfo[] { new ImageInfo() { Name = "dude", Id = 1, Extension = "png" } };
            mi[0].Facets = new FacetAbsBase[] { new FacetString() { Name = "fork", Value = "this" } };

            ImageInfoIO.SaveAllImages(1, mi);
            ImageInfoIO.WaitTillIOFlushed();
            ImageInfoIO.ResetCache();

            var cn = ImageInfoIO.LoadAllImages(1);
            Assert.AreEqual(1, cn.Length, "length of images");
            Assert.AreEqual(1, cn[0].Facets.Length, "# fo facets");
            Assert.AreEqual("fork", cn[0].Facets[0].Name, "facet name");
            Assert.AreEqual("this", (cn[0].Facets[0] as FacetString).Value, "facet value");
        }

        [TestMethod]
        public void TestMarkerFileAfterImageCreated()
        {
            var mi = new ImageInfo[] { new ImageInfo() { Name = "dude", Id = 1, Extension = "png" } };
            ImageInfoIO.SaveAllImages(5, mi);
            ImageInfoIO.WaitTillIOFlushed();
            Assert.IsTrue(Utils.RenderPending(5), "A render was not pending, unexpected");
        }

        [TestMethod]
        [DeploymentItem("testplot1.png")]
        public void TestFirstTimeImageCausesRewrite()
        {
            var data = Utils.LoadImageData("testplot1.png");
            bool didWrite = ImageInfoIO.SaveImage(1, 1, "png", data);
            Assert.IsTrue(didWrite, "Image was not writte");
        }

        [TestMethod]
        [DeploymentItem("testplot1.png")]
        public void TestImageUpdateCausesNoRewrite()
        {
            var data = Utils.LoadImageData("testplot1.png");
            bool didWrite = ImageInfoIO.SaveImage(1, 1, "png", data);
            Assert.IsTrue(didWrite, "Image was not writte");
            didWrite = ImageInfoIO.SaveImage(1, 1, "png", data);
            Assert.IsFalse(didWrite, "Image was written");
        }

        [TestMethod]
        [DeploymentItem("testplot1.png")]
        [DeploymentItem("testplot2.png")]
        public void TestImageUpdateWithNewCausesWrite()
        {
            var data = Utils.LoadImageData("testplot1.png");
            bool didWrite = ImageInfoIO.SaveImage(1, 1, "png", data);
            Assert.IsTrue(didWrite, "Image was not writte");
            data = Utils.LoadImageData("testplot2.png");
            didWrite = ImageInfoIO.SaveImage(1, 1, "png", data);
            Assert.IsTrue(didWrite, "Image was not written");
        }

        [TestMethod]
        [DeploymentItem("testplot1.png")]
        public void TestDeleteCollectionKillsImages()
        {
            var ci = new CollectionInfo() { Name = "hi", Id = 1 };
            CollectionInfoIO.SaveCollection(ci);
            var data = Utils.LoadImageData("testplot1.png");
            bool didWrite = ImageInfoIO.SaveImage(1, 1, "png", data);
            ImageInfoIO.SaveAllImages(1, new ImageInfo[] { new ImageInfo() { Name = "hi", Extension = "png", Id = 1 } });
            CollectionInfoIO.DeleteCollection(ci);
            CollectionInfoIO.SaveCollection(ci);
            Assert.AreEqual(0, ImageInfoIO.LoadAllImages(1).Length, "# of images");
        }

        [TestMethod]
        [DeploymentItem("testplot1.png")]
        public void TestFacetFinder()
        {
            var ci = new CollectionInfo() { Name = "hi", Id = 1 };
            CollectionInfoIO.SaveCollection(ci);
            var data = Utils.LoadImageData("testplot1.png");
            ImageInfoIO.SaveImage(1, 1, "png", data);
            ImageInfoIO.SaveAllImages(1, new ImageInfo[] { new ImageInfo() { Name = "hi",
                Extension = "png",
                Id = 1,
                Facets=new FacetAbsBase[] {
                    new FacetString() {Name = "hi", Value = "dude"},
                    new FacetNumber() {Name = "there", Number = 2.0}
                }
            } });

            var flist = ImageInfoIO.GetDefaultFacetNames(1);
            Assert.AreEqual(2, flist.Length, "# different facets");
            Assert.IsTrue(flist.Any(s => s == "hi"), "hi missing");
            Assert.IsTrue(flist.Any(s => s == "there"), "there missing");
        }

        [TestMethod]
        [DeploymentItem("testplot1.png")]
        public void TestFacetFinder5000Images()
        {
            var ci = new CollectionInfo() { Name = "hi", Id = 1 };
            CollectionInfoIO.SaveCollection(ci);
            var data = Utils.LoadImageData("testplot1.png");
            ImageInfoIO.SaveImage(1, 1, "png", data);

            foreach (var item in Enumerable.Range(0, 5000))
            {
                ImageInfoIO.SaveAllImages(1, new ImageInfo[] { new ImageInfo() { Name = "hi",
                Extension = "png",
                Id = item,
                Facets=new FacetAbsBase[] {
                    new FacetString() {Name = "hi", Value = "dude"},
                    new FacetNumber() {Name = "there", Number = 2.0}
                }
            } });
            }

            var flist = ImageInfoIO.GetDefaultFacetNames(1);
            Assert.AreEqual(2, flist.Length, "# different facets");
            Assert.IsTrue(flist.Any(s => s == "hi"), "hi missing");
            Assert.IsTrue(flist.Any(s => s == "there"), "there missing");
        }
    }
}
